<template>
  <q-page class="q-pa-md">
    <!-- 查询表单 -->
    <q-card flat bordered class="q-mb-md">
      <q-card-section>
        <div class="text-h6">操作日志查询</div>
      </q-card-section>
      <q-card-section>
        <q-form @submit="handleSearch" class="row q-col-gutter-md">
          <q-input
            v-model="searchForm.operName"
            label="操作人员"
            outlined
            dense
            clearable
            class="col-md-3 col-sm-6 col-xs-12"
          />
          <q-select
            v-model="searchForm.businessType"
            label="操作类型"
            :options="businessTypeOptions"
            outlined
            dense
            emit-value
            map-options
            class="col-md-3 col-sm-6 col-xs-12"
          />
          <q-select
            v-model="searchForm.status"
            label="操作状态"
            :options="statusOptions"
            outlined
            dense
            emit-value
            map-options
            class="col-md-3 col-sm-6 col-xs-12"
          />
          <div class="col-md-3 col-sm-6 col-xs-12">
            <q-input v-model="searchForm.dateRange" label="操作时间" outlined dense clearable>
              <template v-slot:append>
                <q-icon name="event" class="cursor-pointer">
                  <q-popup-proxy cover transition-show="scale" transition-hide="scale">
                    <q-date v-model="searchForm.dateRange" range />
                  </q-popup-proxy>
                </q-icon>
              </template>
            </q-input>
          </div>
          <div class="col-md-12 flex justify-end">
            <q-btn type="submit" color="primary" label="查询" class="q-mr-sm" />
            <q-btn @click="resetSearch" label="重置" outline color="primary" />
            <q-btn color="grey" label="导出" icon="download" @click="exportData" class="q-ml-sm" />
          </div>
        </q-form>
      </q-card-section>
    </q-card>

    <!-- 日志表格 -->
    <q-card flat bordered>
      <q-table
        :rows="operationLogs"
        :columns="columns"
        row-key="operId"
        :loading="loading"
        :pagination="pagination"
        @request="onRequest"
        binary-state-sort
        flat
        bordered
      >
        <!-- 操作类型列 -->
        <template v-slot:body-cell-businessType="props">
          <q-td :props="props">
            <q-badge :color="getBusinessTypeColor(props.row.businessType)">
              {{ businessTypeMap[props.row.businessType] || '其他' }}
            </q-badge>
          </q-td>
        </template>

        <!-- 操作状态列 -->
        <template v-slot:body-cell-status="props">
          <q-td :props="props">
            <q-badge :color="props.row.status === '0' ? 'positive' : 'negative'">
              {{ props.row.status === '0' ? '成功' : '失败' }}
            </q-badge>
          </q-td>
        </template>

        <!-- 操作列 -->
        <template v-slot:body-cell-actions="props">
          <q-td :props="props" class="q-gutter-x-sm">
            <q-btn dense color="primary" icon="visibility" @click="showDetailDialog(props.row)">
              <q-tooltip>查看详情</q-tooltip>
            </q-btn>
          </q-td>
        </template>
      </q-table>
    </q-card>

    <!-- 日志详情对话框 -->
    <q-dialog v-model="detailDialog" persistent>
      <q-card style="min-width: 700px; max-width: 800px">
        <q-card-section>
          <div class="text-h6">操作日志详情</div>
        </q-card-section>

        <q-card-section class="q-pt-none">
          <div class="row q-col-gutter-md q-mb-md">
            <div class="col-md-6 col-sm-12">
              <q-input v-model="currentLog.operName" label="操作人员" outlined readonly />
            </div>
            <div class="col-md-6 col-sm-12">
              <q-input
                v-model="businessTypeMap[currentLog.businessType]"
                label="操作类型"
                outlined
                readonly
              />
            </div>
          </div>

          <div class="row q-col-gutter-md q-mb-md">
            <div class="col-md-6 col-sm-12">
              <q-input v-model="currentLog.operIp" label="操作IP" outlined readonly />
            </div>
            <div class="col-md-6 col-sm-12">
              <q-input v-model="currentLog.operLocation" label="操作地点" outlined readonly />
            </div>
          </div>

          <div class="row q-col-gutter-md q-mb-md">
            <div class="col-md-6 col-sm-12">
              <q-input v-model="currentLog.operTime" label="操作时间" outlined readonly />
            </div>
            <div class="col-md-6 col-sm-12">
              <q-input
                :model-value="currentLog.status === '0' ? '成功' : '失败'"
                label="操作状态"
                outlined
                readonly
              />
            </div>
          </div>

          <q-input v-model="currentLog.title" label="模块标题" outlined readonly class="q-mb-md" />

          <q-input v-model="currentLog.method" label="方法名称" outlined readonly class="q-mb-md" />

          <q-input
            v-model="currentLog.requestMethod"
            label="请求方式"
            outlined
            readonly
            class="q-mb-md"
          />

          <q-input
            v-model="currentLog.operatorType"
            label="操作类别"
            outlined
            readonly
            class="q-mb-md"
          />

          <q-input
            v-model="currentLog.jsonResult"
            label="返回结果"
            type="textarea"
            outlined
            readonly
            autogrow
            class="q-mb-md"
          />

          <q-input
            v-model="currentLog.errorMsg"
            label="错误消息"
            type="textarea"
            outlined
            readonly
            autogrow
            v-if="currentLog.status !== '0'"
          />
        </q-card-section>

        <q-card-actions align="right">
          <q-btn label="关闭" color="primary" v-close-popup />
        </q-card-actions>
      </q-card>
    </q-dialog>
  </q-page>
</template>

<script setup>
import { ref, onMounted } from 'vue'
import { useQuasar } from 'quasar'

const $q = useQuasar()

// 表格列定义
const columns = [
  { name: 'operId', label: '日志ID', field: 'operId', align: 'center', sortable: true },
  { name: 'title', label: '模块标题', field: 'title', align: 'left' },
  { name: 'businessType', label: '操作类型', field: 'businessType', align: 'center' },
  { name: 'operName', label: '操作人员', field: 'operName', align: 'center' },
  { name: 'operIp', label: '操作IP', field: 'operIp', align: 'center' },
  { name: 'status', label: '操作状态', field: 'status', align: 'center' },
  { name: 'operTime', label: '操作时间', field: 'operTime', align: 'center', sortable: true },
  { name: 'actions', label: '操作', align: 'center' },
]

// 操作类型选项
const businessTypeOptions = [
  { label: '全部', value: '' },
  { label: '新增', value: '1' },
  { label: '修改', value: '2' },
  { label: '删除', value: '3' },
  { label: '授权', value: '4' },
  { label: '导出', value: '5' },
  { label: '导入', value: '6' },
  { label: '强退', value: '7' },
  { label: '生成代码', value: '8' },
  { label: '清空数据', value: '9' },
]

// 操作类型映射
const businessTypeMap = {
  1: '新增',
  2: '修改',
  3: '删除',
  4: '授权',
  5: '导出',
  6: '导入',
  7: '强退',
  8: '生成代码',
  9: '清空数据',
}

// 操作类型颜色
const getBusinessTypeColor = (type) => {
  const colors = {
    1: 'blue',
    2: 'green',
    3: 'red',
    4: 'purple',
    5: 'orange',
    6: 'teal',
    7: 'pink',
    8: 'indigo',
    9: 'cyan',
  }
  return colors[type] || 'grey'
}

// 状态选项
const statusOptions = [
  { label: '全部', value: '' },
  { label: '成功', value: '0' },
  { label: '失败', value: '1' },
]

// 数据状态
const operationLogs = ref([])
const loading = ref(false)
const pagination = ref({
  page: 1,
  rowsPerPage: 10,
  rowsNumber: 0,
})
const searchForm = ref({
  operName: '',
  businessType: '',
  status: '',
  dateRange: { from: '', to: '' },
})

// 日志详情相关
const detailDialog = ref(false)
const currentLog = ref({
  operId: '',
  title: '',
  businessType: '',
  method: '',
  requestMethod: '',
  operatorType: '',
  operName: '',
  operIp: '',
  operLocation: '',
  operParam: '',
  jsonResult: '',
  status: '',
  errorMsg: '',
  operTime: '',
})

// 初始化加载数据
onMounted(() => {
  loadOperationLogs()
})

// 加载操作日志
function loadOperationLogs(props) {
  if (!props) {
    props = { pagination: pagination.value }
  }

  loading.value = true
  const { page, rowsPerPage } = props.pagination

  // 模拟API请求
  setTimeout(() => {
    // 这里应该是实际的API调用
    // 模拟数据
    const mockData = Array.from({ length: rowsPerPage }, (_, i) => ({
      operId: (page - 1) * rowsPerPage + i + 1,
      title: ['用户管理', '角色管理', '菜单管理', '部门管理', '岗位管理'][i % 5],
      businessType: ['1', '2', '3', '4', '5', '6', '7', '8', '9'][i % 9],
      method: [
        'com.xxx.system.controller.UserController.add()',
        'com.xxx.system.controller.RoleController.edit()',
        'com.xxx.system.controller.MenuController.remove()',
        'com.xxx.system.controller.DeptController.export()',
        'com.xxx.system.controller.PostController.import()',
      ][i % 5],
      requestMethod: ['POST', 'PUT', 'DELETE', 'GET', 'POST'][i % 5],
      operatorType: ['MANAGE', 'MOBILE', 'OTHER'][i % 3],
      operName: ['admin', 'test', 'dev', 'user', 'manager'][i % 5],
      operIp: ['192.168.1.' + (i + 1), '10.0.0.' + (i + 1), '172.16.0.' + (i + 1)][i % 3],
      operLocation: ['内网IP', '北京市', '上海市', '广州市', '深圳市'][i % 5],
      operParam: JSON.stringify(
        {
          userId: i + 1,
          userName: ['张三', '李四', '王五', '赵六', '钱七'][i % 5],
          roleId: [1, 2, 3][i % 3],
        },
        null,
        2,
      ),
      jsonResult: JSON.stringify(
        {
          code: 200,
          msg: '操作成功',
          data: null,
        },
        null,
        2,
      ),
      status: i % 10 === 0 ? '1' : '0', // 10%的概率模拟失败
      errorMsg: i % 10 === 0 ? 'NullPointerException: 对象为空' : '',
      operTime: new Date(Date.now() - i * 3600 * 1000).toISOString(),
    }))

    // 应用查询条件
    let filteredData = [...mockData]
    if (props.filter.operName) {
      filteredData = filteredData.filter((item) => item.operName.includes(props.filter.operName))
    }
    if (props.filter.businessType) {
      filteredData = filteredData.filter((item) => item.businessType === props.filter.businessType)
    }
    if (props.filter.status) {
      filteredData = filteredData.filter((item) => item.status === props.filter.status)
    }
    if (props.filter.dateRange.from && props.filter.dateRange.to) {
      const fromDate = new Date(props.filter.dateRange.from)
      const toDate = new Date(props.filter.dateRange.to)
      filteredData = filteredData.filter((item) => {
        const itemDate = new Date(item.operTime)
        return itemDate >= fromDate && itemDate <= toDate
      })
    }

    operationLogs.value = filteredData
    pagination.value.rowsNumber = filteredData.length
    pagination.value.page = page
    pagination.value.rowsPerPage = rowsPerPage
    loading.value = false
  }, 500)
}

// 表格请求方法
function onRequest(props) {
  loadOperationLogs(props)
}

// 查询处理
function handleSearch() {
  pagination.value.page = 1
  onRequest({
    pagination: pagination.value,
    filter: searchForm.value,
  })
}

// 重置查询
function resetSearch() {
  searchForm.value = {
    operName: '',
    businessType: '',
    status: '',
    dateRange: { from: '', to: '' },
  }
  handleSearch()
}

// 显示详情对话框
function showDetailDialog(row) {
  currentLog.value = {
    ...row,
    operParam: formatJson(row.operParam),
    jsonResult: formatJson(row.jsonResult),
  }
  detailDialog.value = true
}

// 格式化JSON
function formatJson(json) {
  try {
    const obj = JSON.parse(json)
    return JSON.stringify(obj, null, 2)
  } catch (e) {
    return json
  }
}

// 导出数据
function exportData() {
  $q.notify({
    type: 'positive',
    message: '导出成功',
  })
}
</script>

<style lang="scss" scoped>
.q-table {
  thead tr th {
    font-weight: bold;
    background-color: #f5f5f5;
  }

  tbody tr:hover {
    background-color: #f5f5f5;
  }
}

// 固定详情对话框的宽度
.q-dialog__inner--minimized > div {
  max-width: 800px;
}
</style>
